<!-- 导出PDF -->
<template>
  <el-dialog v-if="props.show" v-model="props.show" :title="props.title" :close-on-click-modal="false"
    :close-on-press-escape="false" width="60%" top="18vh" @close="onHideDetails">
    <el-form v-loading="indexStore.moduleLoading" :model="data.query" :rules="data.rules" ref="addQuery" status-icon :validate-on-rule-change="false"
      :scroll-to-error="true">
      <form-item title="商户类别" :pass="true" value="operator_id" v-if="!indexStore.is_general_agent">
        <el-select class="formItem240" v-model="data.query.operator_id" placeholder="请选择" filterable
          @change="getCommercialList">
          <el-option label="全部" :value="-1" />
          <el-option class="flexBetween" v-for="item in indexStore.operatorArray" :key="item.value"
            :label="'【' + item.value + '】' + item.label" :value="item.value" v-show="item.status && item.type != 1">
            【{{ item.value }}】{{ item.label }}
            <el-tag size="small" :type="item.value == 1 ? 'success' : item.currency == 1 ? 'danger' : 'warning'"
              style="font-size:10px;">
              {{ item.value == 1 ? '直营' : item.currency == 1 ? '多货币' : '正常总代' }}
            </el-tag>
          </el-option>
        </el-select>
        <span class="tipsText">({{ t('com_1') }})</span>
      </form-item>
      <form-item title="商户" :pass="true" value="agent_ids">
        <el-select class="imWidth100" v-model="data.query.agent_ids" placeholder="请选择" filterable multiple
          @change="chooseAgent">
          <el-option label="全部" :value="-1" />
          <el-option v-for="item in data.commercialArray" :key="item.value" :label="'【' + item.value + '】' + item.label"
            :value="item.value" v-show="!item.type" />
        </el-select>
        <span class="tipsText">(选择导出账单的商户)</span>
      </form-item>
      <form-item title="账单类型">
        <el-radio-group v-model="data.query.calculation" size="large">
          <el-radio-button label="分成账单" :value="0" />
          <el-radio-button label="返佣账单" :value="1" v-if="!indexStore.is_general_agent" />
        </el-radio-group>
      </form-item>
      <form-item title="导出时间段" :pass="true" value="date">
        <div style="width: 350px !important;">
          <el-date-picker v-model="data.query.date" type="daterange" range-separator="-" start-placeholder="请选择开始时间"
            end-placeholder="请选择结束时间" value-format="YYYY-MM-DD" clearable :disabled-date="indexStore.disabledDateTime" style="width: 350px !important;" />
          <span class="tipsText">(选择导出账单数据的日期)</span>
        </div>
      </form-item>
      <form-item title="钱包">
        <el-select v-model="data.query.type" placeholder="请选择" filterable>
          <el-option v-for="(item, index) in data.addressList" :key="index" :label="item.label" :value="item.value" />
        </el-select>
        <span class="tipsText">(下拉选择TRC20、ERC20、BEP20；默认选择TRC20)</span>
      </form-item>
      <form-item title="钱包地址" value="address">
        <el-input class="width320" v-model="data.query.address" placeholder="请输入" clearable
          onKeyUp="value=value.replace(/[\W]/g,'')" />
        <span class="tipsText">(选填！输入钱包地址，导出后保存地址)</span>
      </form-item>
    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button type="warning" v-loading="indexStore.moduleLoading" @click="exportTypePDF">导出账单</el-button>
      </div>
    </template>
  </el-dialog>

  <!-- 账单样式 -->
  <div id="pdfContent" ref="pdfContent" >
    <PdfDocument :show="data.isShowExport" :query="data.query" :datalist="data.allData"/>
  </div>
  <!-- 导出文件展示 -->
  <el-dialog v-model="data.iShowExportPDF" title="账单导出" :close-on-click-modal="false" :close-on-press-escape="false" :show-close="false"
    width="55%" top="18vh">
    <template #header>
      <p class="box-title">账单导出({{ data.pdfList.length }}) (<span class="tipsTextRed">账单导出中~请耐心等待</span>)</p>
    </template>
    <div class="pdf_box flexWrap">
      <div class="width25 marginTB5" v-for="(item,index) in data.pdfList" :key="index">
        <span class="mustPass">{{ item.label }}</span> 账单已生成<el-icon class="colorGreen" style="margin-top: 3px;"><CircleCheck /></el-icon>
      </div>
    </div>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, reactive, watch, nextTick } from 'vue'
import html2canvas from 'html2canvas'
import jsPDF from 'jspdf'
import JSZip from 'jszip';
import { saveAs } from 'file-saver';
import { ElMessage,ElMessageBox } from 'element-plus'
import type { FormInstance } from 'element-plus'
import PdfDocument from '@/components/FormItem/PdfDocument.vue'
import { getCommercialTotal } from '@/api/common'
import { throttle, selectToLabel, ArrayReduce, StringReplace } from '@/utils/index'
import { BigWan, BigDiv, BigTimes, BigTofixedFour } from '@/utils/math'
import { setTimeValue, getThirtyMonth, getDateDay } from '@/utils/time'
import { Time } from '@/utils/serverTime'
import { getWalletAddress, addWalletAddress, getCheckReport } from '@/api/merchant'
import { useI18n } from 'vue-i18n'
const { t } = useI18n()
import { useStore } from '@/stores/index'

const indexStore = useStore()

const props = defineProps({
  show: {
    type: Boolean,
    default: () => {
      return false
    }
  },
  title: {
    type: String,
    default: () => {
      return ''
    }
  },
})

const data = reactive({
  query: {
    operator_id: -1,
    agent_ids: [-1],
    date: getThirtyMonth(),
    type: 'TRC20',
    address: '',
    number: '',
    calculation: 0
  },
  list: [] as any,
  commercialArray: indexStore.agentArray,
  addressList: [
    { label: 'TRC20', value: 'TRC20' },
    { label: 'ERC20', value: 'ERC20' },
    { label: 'BEP20', value: 'BEP20' },
  ],
  rules: {
    agent_ids: [{ required: true, message: '请选择商户', trigger: 'change' }],
    date: [{ required: true, message: '请选择导出日期', trigger: 'change' }],
  },
  isShowExport: false,
  iShowExportPDF: false,
  title: indexStore.BackOperator,
  allData:[{title: '账单报表', // 标题
    username: '', //  接收方
    number: '', //  账单编号
    date_start: '', //  日期开始
    date_end: '', //  日期结束
    list: [{
      index: 0,
      agent_id: 0,
      symbol: '',
      total_game_income: 0,
      usdt_exchange_rate: 0,
      total_bet_count: 0,
      calculation: 0,
      total_usdt: 0,
    }] as any[], //  数据
    summation: 0, //  汇总
    type: 'TRC20', //  钱包类型
    address: '', //  地址
  }] as any[],
  timeInterval:null,
  pdfList:[] as any[]
})

watch(
  () => props.show,
  async (value) => {
    if (value) {
      data.commercialArray = indexStore.agentArray
      getWalletAddressInfo()
    }
  },
)

const getSearchList = async () => {
  indexStore.setModuleLoading(true)
  let queryDetails = JSON.parse(JSON.stringify(data.query));
  queryDetails = setTimeValue(queryDetails)
  const all = data.query.agent_ids.find((item: number) => item == -1)
  if (data.query.operator_id == -1) {
    queryDetails.operator_ids = []
    indexStore.operatorArray.forEach((item: any) => {
      queryDetails.operator_ids.push(item.value)
    })
  }else{
    queryDetails.operator_ids = [data.query.operator_id]
  }
  if (all) {
    queryDetails.agent_ids = []
    data.commercialArray.forEach((item: any) => {
      queryDetails.agent_ids.push(item.value)
    })
  }
  let res = await getCheckReport({
    agent_ids: queryDetails.agent_ids,
    operator_ids: queryDetails.operator_ids,
    start_time: queryDetails.start_time,
    end_time: queryDetails.end_time,
    calculation: queryDetails.calculation,
  })
  if(!res.data){
    return ElMessage.error('导出商户无数据')
  }
  let BillKeys=Object.keys(res.data),dataList = [] as any[];
  BillKeys.forEach((key:string)=> {
    // 账单订单号
    data.query.number = setBillingNumber(key)
    let summy = [] as number[], list = [] as any;
    res.data[key].forEach((item: any, index: number) => {
      item.index = index + 1
      item.total_game_income = BigWan(item.total_game_income)
      item.game_income = BigWan(BigTimes(item.game_income, item.usdt_exchange_rate))
      // 结算比列 
      if(!indexStore.is_general_agent){
        item.total_game_income = BigDiv(item.total_game_income,item.settlement_ratio)
        item.game_income = BigDiv(item.game_income,item.settlement_ratio)
      }
      // 汇总
      summy.push(item.game_income)
      // 换算USDT
      item.total_bet_count = BigTimes(item.total_game_income, item.usdt_exchange_rate)
      // 分成账单
      if(!data.query.calculation){
        item.config_ggr = [], item.ggrKey = Object.keys(item.ggr?item.ggr:[])
        item.ggrKey.forEach((key: number) => {
          item.config_ggr.push({ platform: Number(key), radio: item.ggr[Number(key)], })
        })
      }
      // 直营的要分商户导出 非直营的以总代为单位导出
      if(key=='1'){
        list.push(item)
      }
    })
    if(key!='1'){
      list = res.data[key]
    }
    // 所有数据装在一个盒子里面
    let name = !indexStore.is_general_agent?selectToLabel(indexStore.agentArray, key)?selectToLabel(indexStore.agentArray, key):selectToLabel(indexStore.operatorArray, key):indexStore.userInfo.username
    dataList.push({
      title: indexStore.BackOperator+'账单报表', // 标题
      username: name, //  接收方
      number: setBillingNumber(key), //  账单编号
      date_start: queryDetails.date[0], //  日期开始
      date_end: queryDetails.date[1], //  日期结束
      list: list as any[], //  数据
      summation: summy.length?BigTofixedFour(ArrayReduce(summy)):10, //  汇总
      type: data.query.type, //  钱包类型
      address: data.query.address, //  地址
    })
  })
  data.allData = dataList
  data.isShowExport = true
  console.log(data.allData);
  if(data.query.operator_id == -1){
    ElMessageBox.confirm('确认导出全部商户账单？', '处理',{
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning'
    }).then(async () => {
      exportPDFAgent()
    }).catch(() => { })
  }else{
    exportPDFAgent()
  }
}
const exportPDFAgent = ()=>{
  indexStore.setModuleLoading(true)
  data.pdfList = []
  nextTick(async () => {
    const zip = new JSZip();
    data.iShowExportPDF = true
    for (const [index,item] of data.allData.entries()) {
      let pdfBlob = await Promise.all([exportPDF(item.number,item.username)])
      console.log(`这是第 ${index + 1} 个商户 ${item.username}.PDF 文件`)
      data.pdfList.push({label:item.username})
      zip.file(`${data.title}账单${data.query.date[0].slice(0, 7)}_${item.username}.pdf`, pdfBlob[0]);
    }
    // 生成 ZIP 文件并触发下载
    try {
      console.log("开始保存ZIP文件")
      const zipContent = await Promise.all([zip.generateAsync({ type: 'blob' })]);
      saveAs(zipContent[0], 'documents.zip'); // 下载 ZIP 文件
      indexStore.setModuleLoading(false)
      ElMessage.success(`导出完成,一共${data.pdfList.length}`)
      onHideDetails()
    } catch (error) {
      console.error('生成 ZIP 文件失败:', error);
    }
  })
}

// 账单订单号 = OMG+总代/商户id+当前日期+当前时间戳
const setBillingNumber =(id:string) => {
  return 'OMG'+id+StringReplace(getDateDay(0),'-','')+new Time().toTimestamp()
}

// 获取钱包地址
const getWalletAddressInfo = async () => {
  let res = await getWalletAddress({});
  if (res.data.collection_address) {
    data.query.type = res.data.collection_address
  }
  if (res.data.wallet_address) {
    data.query.address = res.data.wallet_address
  }
}
// 设置钱包地址
const setWalletAddress = async () => {
  await addWalletAddress({
    collection_address: data.query.type,
    wallet_address: data.query.address
  })
}

// 选择总代-查询总代下所有商户
const getCommercialList = async (id: any) => {
  data.query.agent_ids = [-1]
  if(id==-1){
    data.commercialArray = indexStore.agentArray
  }else{
    let res = await getCommercialTotal({ operated_id: id })
    data.commercialArray = res.data as any
  }
}
const chooseAgent = async (row: any) => {
  const all = row.find((item: number) => item == -1)
  if (all) {
    data.query.agent_ids = [-1] as any
  } else {
    data.query.agent_ids = row
  }
}

// 选择导出
const addQuery = ref<FormInstance>()
const exportTypePDF = throttle(async () => {
  if (!addQuery.value) return
  await addQuery.value.validate(async (valid, fields) => {
    if (valid) {
      setWalletAddress()
      getSearchList()
    }
  })
}, 20000)

// 导出PDF
const exportPDF = async (number?:string,name?:string) => {
  const content = document.getElementsByClassName(number as string) as any;
  // 使用 html2canvas 将页面元素转换为画布
  const canvas = await html2canvas(content[0],{
    allowTaint: false,
    logging: false,
    useCORS: true,
    scale: 4, //按比例增加分辨率
  })
  // 创建一个新的jspdf实例
  const pdf = new jsPDF('p', 'mm', 'a4');
  //----- 将画布转换为图片
  let ctx = canvas.getContext('2d') as any,a4w = 210,
  a4h = 272, //A4大小，210mm x 297mm
  imgHeight = Math.floor((a4h * canvas.width) / a4w), //按A4显示比例换算一页图像的像素高度
  renderedHeight = 0;
  while (renderedHeight < canvas.height) {
    var page = document.createElement('canvas') as any;
    page.width = canvas.width;
    page.height = Math.min(imgHeight, canvas.height - renderedHeight); //可能内容不足一页
    //用getImageData剪裁指定区域，并画到前面创建的canvas对象中
    page.getContext('2d').putImageData(
        ctx.getImageData( 0,renderedHeight, canvas.width, Math.min(imgHeight, canvas.height - renderedHeight),),0,0,);
    pdf.addImage(page.toDataURL('image/jpeg', 1.0), 'JPEG', 0, 0, a4w, Math.min(a4h, (a4w * page.height) / page.width), ); //添加图像到页面
    renderedHeight += imgHeight;
    if (renderedHeight < canvas.height) {
      pdf.addPage(); //如果后面还有内容，添加一个空页
    }
  }
  //------ 将画布转换为图片
  // let img = canvas.toDataURL('image/png',1.0);
  // // 将图片添加到PDF中
  // const imgProps = pdf.getImageProperties(img);
  // const pdfWidth = pdf.internal.pageSize.getWidth();
  // const pdfHeight = (imgProps.height * pdfWidth) / imgProps.width;
  // pdf.addImage(img, 'PNG', 0, 0, pdfWidth, pdfHeight);
  // // 保存生成的PDF
  // pdf.save(`${data.title}账单${data.query.date[0].slice(0, 7)}_${name}.pdf`);
  
  return pdf.output("blob")
};

// 重置
const emit = defineEmits(['onHideDetails'])
const onHideDetails = () => {
  data.isShowExport = false
  data.iShowExportPDF = false
  data.allData = [{title: '账单报表', // 标题
    username: '', //  接收方
    number: '', //  账单编号
    date_start: '', //  日期开始
    date_end: '', //  日期结束
    list: [{
      index: 0,
      agent_id: 0,
      symbol: '',
      total_game_income: 0,
      usdt_exchange_rate: 0,
      total_bet_count: 0,
      calculation: 0,
      total_usdt: 0,
    }] as any[], //  数据
    summation: 0, //  汇总
    type: 'TRC20', //  钱包类型
    address: '', //  地址
  }]
  data.query = {
    operator_id: -1,
    agent_ids: [-1],
    date: getThirtyMonth(),
    type: 'TRC20',
    address: '',
    number: '',
    calculation: 0
  }
  emit('onHideDetails', false)
}
</script>

<style scoped lang="scss">
@font-face {
  font-family: 'YaHei';
  src: url(@/assets/font/msyhl.ttc);
  font-weight: normal;
  font-style: normal;
}
.pdf_box{
  width: 100%;
  line-height: 30px;
  max-height: 600px;
  overflow: auto;
}
.fontWeight {
  font-weight: 600 !important;
}

.fontSize16 {
  font-size: 16px !important;
}

.pdf {
  font-size: 21px;
  padding: 20px 40px;
  font-family: 'YaHei', sans-serif;

  .box-title {
    font-size: 34px;
    color: #0e8a88;
  }

  .summation {
    width: 270px;

    .width200 {
      border-radius: 3px;
      padding: 5px;
      background-color: #EEEEEE;
    }
  }

  .collection {
    width: 360px;
    font-size: 16px;
    border: 1px solid #dddddd;

    div {
      margin: -1px;
      padding: 5px 0;
      border: 1px solid #dddddd;
    }

    .address {
      color: #000000;
      background-color: #EEEEEE;
    }
  }
}
</style>